package com.aliothservice.catfish.product;

import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.web.multipart.MultipartFile;

import com.aliothservice.catfish.SessionManager;
import com.aliothservice.catfish.data.ProductCategory;
import com.aliothservice.catfish.data.TransportationTemperature;
import com.aliothservice.catfish.data.VehicleLengthDef;
import com.aliothservice.catfish.data.WarehouseTemperature;
import com.aliothservice.catfish.identity.data.IdentityDataManager;
import com.aliothservice.catfish.identity.data.User;
import com.aliothservice.catfish.product.data.ProductDataManager;
import com.aliothservice.catfish.product.data.ProductPending;
import com.aliothservice.catfish.product.data.VehiclePending;
import com.aliothservice.catfish.product.data.VehicleSpec;
import com.aliothservice.catfish.product.data.WarehousePending;
import com.aliothservice.catfish.product.request.AddDriverRequest;
import com.aliothservice.catfish.product.request.AddProductPendingRequest;
import com.aliothservice.catfish.product.request.AddVehiclePendingRequest;
import com.aliothservice.catfish.product.request.AddWarehousePendingRequest;
import com.aliothservice.catfish.product.request.ApprovedProductListRequest;
import com.aliothservice.catfish.product.request.ApprovedVehicleListRequest;
import com.aliothservice.catfish.product.request.ApprovedWarehouseListRequest;
import com.aliothservice.catfish.product.request.CancelCompleteVehicleServiceRequest;
import com.aliothservice.catfish.product.request.CancelProductServiceRequest;
import com.aliothservice.catfish.product.request.CancelWarehouseServiceRequest;
import com.aliothservice.catfish.product.request.CompleteProductPendingRequest;
import com.aliothservice.catfish.product.request.CompleteVehiclePendingRequest;
import com.aliothservice.catfish.product.request.CompleteVehicleServiceCountingRequest;
import com.aliothservice.catfish.product.request.CompleteWarehousePendingRequest;
import com.aliothservice.catfish.product.request.DeleteApprovedProductRequest;
import com.aliothservice.catfish.product.request.DeleteApprovedVehicleRequest;
import com.aliothservice.catfish.product.request.DeleteApprovedWarehouseRequest;
import com.aliothservice.catfish.product.request.DeleteDriverRequest;
import com.aliothservice.catfish.product.request.DeleteRejectedProductRequest;
import com.aliothservice.catfish.product.request.DeleteRejectedVehicleRequest;
import com.aliothservice.catfish.product.request.DeleteRejectedWarehouseRequest;
import com.aliothservice.catfish.product.request.DriverListingRequest;
import com.aliothservice.catfish.product.request.DriverResourceRequest;
import com.aliothservice.catfish.product.request.InReviewProductPendingListRequest;
import com.aliothservice.catfish.product.request.InReviewVehiclePendingListRequest;
import com.aliothservice.catfish.product.request.InReviewWarehousePendingListRequest;
import com.aliothservice.catfish.product.request.ProductCountingRequest;
import com.aliothservice.catfish.product.request.ProductForProductServiceRequest;
import com.aliothservice.catfish.product.request.ProductInfoRequest;
import com.aliothservice.catfish.product.request.ProductResourceRequest;
import com.aliothservice.catfish.product.request.ProductServiceCountingRequest;
import com.aliothservice.catfish.product.request.ProductServiceListingRequest;
import com.aliothservice.catfish.product.request.ProductSpecListingRequest;
import com.aliothservice.catfish.product.request.PublishCompleteVehicleServiceRequest;
import com.aliothservice.catfish.product.request.PublishProductServiceRequest;
import com.aliothservice.catfish.product.request.PublishWarehouseServiceRequest;
import com.aliothservice.catfish.product.request.RejectedProductListRequest;
import com.aliothservice.catfish.product.request.RejectedVehicleListRequest;
import com.aliothservice.catfish.product.request.RejectedWarehouseListRequest;
import com.aliothservice.catfish.product.request.SearchCompleteVehicleServiceRequest;
import com.aliothservice.catfish.product.request.SearchProductServiceRequest;
import com.aliothservice.catfish.product.request.SearchWarehouseServiceRequest;
import com.aliothservice.catfish.product.request.UpdateDriverRequest;
import com.aliothservice.catfish.product.request.UpdateProductInfoRequest;
import com.aliothservice.catfish.product.request.UpdateVehicleInfoRequest;
import com.aliothservice.catfish.product.request.UpdateWarehouseInfoRequest;
import com.aliothservice.catfish.product.request.VehicleCountingRequest;
import com.aliothservice.catfish.product.request.VehicleInfoRequest;
import com.aliothservice.catfish.product.request.VehicleResourceRequest;
import com.aliothservice.catfish.product.request.VehicleServiceListingRequest;
import com.aliothservice.catfish.product.request.VehicleSpecListingRequest;
import com.aliothservice.catfish.product.request.VehicleSpecStockRequest;
import com.aliothservice.catfish.product.request.VehiclesForCompleteVehicleServiceRequest;
import com.aliothservice.catfish.product.request.WarehouseCountingRequest;
import com.aliothservice.catfish.product.request.WarehouseForWarehouseServiceRequest;
import com.aliothservice.catfish.product.request.WarehouseInfoRequest;
import com.aliothservice.catfish.product.request.WarehouseResourceRequest;
import com.aliothservice.catfish.product.request.WarehouseServiceCountingRequest;
import com.aliothservice.catfish.product.request.WarehouseServiceListingRequest;
import com.aliothservice.catfish.product.request.WarehouseSpecListingRequest;
import com.mongodb.gridfs.GridFSDBFile;

public class ProductController {
	
	public Map<String, String> addVehiclePending(AddVehiclePendingRequest req) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==req.getLicensePlate()) || (null==req.getProvince()) || (null==req.getCity()) || (null==req.getPurchaseDate()) || 
				(null==req.getFullLoadMass()) || (null==req.getFullLoadWeight()) || (null==req.getTemperatureMin()) || 
				(null==req.getTemperatureMax()) || (null==req.getLengthDef()) || (null==req.getOwner()) || (null==req.getOdometer()) ||
				(null==req.getManInChargeName()) || (null==req.getManInChargePhoneNumber())) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		
		// validate user
		User user = identityDataManager.findUser(phoneNumber);
		if ((null==user) || (0!=user.getAccountStatus().compareTo(User.ACCOUNT_STATUS_VERIFIED))) {
			map.put("errorCode", "402");
			map.put("errorMessage", "not allowed request");
			return map;
		}
		
		// presence checking
		if (productDataManager.checkPresenceOfInReviewVehiclePending(phoneNumber, req.getLicensePlate()) || 
				productDataManager.checkPresenceOfApprovedVehicle(phoneNumber, req.getLicensePlate())) {
			map.put("errorCode", "403");
			map.put("errorMessage", "vehicle in review or has added");
			return map;
		}
		
		// create pending as necessary
		VehiclePending pending = productDataManager.findUpsertedVehiclePending(phoneNumber);
		if (null == pending) {
			pending = new VehiclePending();
			pending.setUserId(phoneNumber);
		}
		
		// update values
		pending.setLicensePlate(req.getLicensePlate());
		pending.setProvince(req.getProvince());
		pending.setCity(req.getCity());
		DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		try {
			pending.setPurchaseDate(formatter.parse(req.getPurchaseDate()));
		} catch (ParseException e) {
			map.put("errorCode", "401");
			map.put("errorMessage", "invalid parameters");
			return map;
		}
		pending.setFullLoadMass(Integer.valueOf(req.getFullLoadMass()));
		pending.setFullLoadWeight(Integer.valueOf(req.getFullLoadWeight()));
		pending.setTemperatureMin(Integer.valueOf(req.getTemperatureMin()));
		pending.setTemperatureMax(Integer.valueOf(req.getTemperatureMax()));
		pending.setLengthDef(req.getLengthDef());
		pending.setOwner(req.getOwner());
		pending.setOdometer(Integer.valueOf(req.getOdometer()));
		pending.setManInChargeName(req.getManInChargeName());
		pending.setManInChargePhoneNumber(req.getManInChargePhoneNumber());
		if (null != req.getRefId()) {
			pending.setRefId(req.getRefId());
		}
		productDataManager.addVehiclePending(phoneNumber, pending);
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> addWarehousePending(AddWarehousePendingRequest req) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==req.getName()) || (null==req.getOwner()) || (null==req.getOwnerPhoneNumber()) || (null==req.getProvince()) || 
			(null==req.getCity()) || (null==req.getDistrict()) || (null==req.getAddress()) || (null==req.getFoundDate()) ||
			(null==req.getTemperatureLevels()) || (null==req.getManInChargeName()) || (null==req.getManInChargePhoneNumber())) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		
		// validate user
		User user = identityDataManager.findUser(phoneNumber);
		if ((null==user) || (0!=user.getAccountStatus().compareTo(User.ACCOUNT_STATUS_VERIFIED))) {
			map.put("errorCode", "402");
			map.put("errorMessage", "not allowed request");
			return map;
		}
		
		// presence checking
		if (productDataManager.checkPresenceOfInReviewWarehousePending(phoneNumber, req.getName()) || 
			(productDataManager.checkPresenceOfApprovedWarehouse(phoneNumber, req.getName()))) {
			map.put("errorCode", "402");
			map.put("errorMessage", "not allowed request - duplicated name: + " + req.getName());
			return map;
		}
		
		// upsert pending
		if (!productDataManager.addWarehousePending(phoneNumber, req)) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to add");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> addProductPending(AddProductPendingRequest req) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==req.getName()) || (null==req.getCategory()) || (null==req.getOwnerName()) || (null==req.getOwnerPhoneNumber()) ||
			(null==req.getProvince()) || (null==req.getCity()) || (null==req.getDistrict()) || (null==req.getOriginProvince()) ||
			(null==req.getOriginCity()) || (null==req.getOriginDistrict()) || (null==req.getManInChargeName()) ||
			(null==req.getManInChargePhoneNumber())) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		
		// validate user
		User user = identityDataManager.findUser(phoneNumber);
		if ((null==user) || (0!=user.getAccountStatus().compareTo(User.ACCOUNT_STATUS_VERIFIED))) {
			map.put("errorCode", "402");
			map.put("errorMessage", "not allowed request");
			return map;
		}

		// presence checking
		if (productDataManager.checkPresenceOfInReviewProductPending(phoneNumber, req.getName()) || 
			productDataManager.checkPresenceOfApprovedProduct(phoneNumber, req.getName())) {
			map.put("errorCode", "402");
			map.put("errorMessage", "not allowed request - duplicated name: + " + req.getName());
			return map;
		}
		
		// upsert pending
		if (!productDataManager.addProductPending(phoneNumber, req)) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to add");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> completeVehiclePending(CompleteVehiclePendingRequest req) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate state
		VehiclePending pending = productDataManager.findUpsertedVehiclePending(phoneNumber);
		if ((null==pending) || (null==pending.getLicensePlate()) || (null==pending.getInsuranceImageId()) || (null==pending.getTransportationLicenseImageId()) || 
				(null==pending.getVehiclePhotoId()) || (null==pending.getVehicleInsidePhotoId())) {
			map.put("errorCode", "401");
			map.put("errorMessage", "invalid state - missing data or photos");
			return map;
		}
		
		// mark as completed
		String pendingId = productDataManager.completeVehiclePending(pending);
		if (null == pendingId) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to complete");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		map.put("pendingId", pendingId);
		return map;
	}
	
	public Map<String, String> completeWarehousePending(CompleteWarehousePendingRequest req) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate state
		WarehousePending pending = productDataManager.findUpsertedWarehousePending(phoneNumber);
		if ((null==pending) || (null==pending.getName()) || (null==pending.getWarehousePhotoId()) || (null==pending.getWarehouseInsidePhotoId())) {
			map.put("errorCode", "401");
			map.put("errorMessage", "invalid state, missing name or photos");
			return map;
		}
		
		// mark as completed
		String pendingId = productDataManager.completeWarehousePending(pending); 
		if (null == pendingId) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to complete");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		map.put("pendingId", pendingId);
		return map;
	}
	
	public Map<String, String> completeProductPending(CompleteProductPendingRequest req) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate state
		ProductPending pending = productDataManager.findUpsertedProductPending(phoneNumber);
		if ((null==pending) || (null==pending.getName()) || (null==pending.getProductPhotoId())) {
			map.put("errorCode", "401");
			map.put("errorMessage", "invalid state, missing name or photos");
			return map;
		}
		
		// mark as completed
		if (!productDataManager.completeProductPending(pending)) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to complete");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> addVehiclePendingResource(String token, String type, MultipartFile file) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(token);
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==type) || (null==file)) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		if ((0!=type.compareTo("vehicle")) && (0!=type.compareTo("transportationLicense")) && (0!=type.compareTo("insurance")) && (0!=type.compareTo("vehicleInside"))) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters - invalid type");
			return map;
		}
		
		// perform resource update
		String imageId;
		try {
			imageId = productDataManager.addVehiclePendingResource(phoneNumber, type, file);
			if (null == imageId) {
				map.put("errorCode", "500");
				map.put("errorMessage", "failed to store");
				return map;
			}
		} catch (IOException e) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to store");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, token);
		
		map.put("imageId", imageId);
		return map;		
	}
	
	public Map<String, String> updateVehicleResource(String token, String vehicleId, String type, MultipartFile file) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(token);
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==type) || (null==file) || (null==vehicleId)) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		if ((0!=type.compareTo("transportationLicense")) && (0!=type.compareTo("insurance"))) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters - invalid type");
			return map;
		}
		
		// perform resource update
		String imageId;
		try {
			imageId = productDataManager.updateVehicleResource(phoneNumber, vehicleId, type, file);
			if (null == imageId) {
				map.put("errorCode", "500");
				map.put("errorMessage", "failed to store");
				return map;
			}
		} catch (IOException e) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to store");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, token);
		
		map.put("imageId", imageId);
		return map;		
	}
	
	public Map<String, String> cropVehiclePendingResource(String token, String imageId, String type, String crop) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(token);
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==type) || (null==imageId) || (null==crop)) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		if ((0!=type.compareTo("vehicle")) && (0!=type.compareTo("vehicleInside"))) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters - invalid type");
			return map;
		}
		if (crop.split(":").length != 3) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters - invalid crop");
			return map;
		}
		
		// perform resource update
		String croppedImageId;
		try {
			croppedImageId = productDataManager.cropVehiclePendingResource(phoneNumber, imageId, type, crop);
			if (null == croppedImageId) {
				map.put("errorCode", "500");
				map.put("errorMessage", "failed to store");
				return map;
			}
		} catch (IOException e) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to store");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, token);
		
		map.put("imageId", croppedImageId);
		return map;		
	}
	
	public Map<String, String> cropWarehousePendingResource(String token, String imageId, String type, String crop) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(token);
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==type) || (null==imageId) || (null==crop)) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		if ((0!=type.compareTo("warehouse")) && (0!=type.compareTo("warehouseInside"))) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters - invalid type");
			return map;
		}
		if (crop.split(":").length != 3) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters - invalid crop");
			return map;
		}
		
		// perform resource update
		String croppedImageId;
		try {
			croppedImageId = productDataManager.cropWarehousePendingResource(phoneNumber, imageId, type, crop);
			if (null == croppedImageId) {
				map.put("errorCode", "500");
				map.put("errorMessage", "failed to store");
				return map;
			}
		} catch (IOException e) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to store");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, token);
		
		map.put("imageId", croppedImageId);
		return map;		
	}
	
	public Map<String, String> cropProductPendingResource(String token, String imageId, String crop) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(token);
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==imageId) || (null==crop)) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		if (crop.split(":").length != 3) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters - invalid crop");
			return map;
		}
		
		// perform resource update
		String croppedImageId;
		try {
			croppedImageId = productDataManager.cropProductPendingResource(phoneNumber, imageId, crop);
			if (null == croppedImageId) {
				map.put("errorCode", "500");
				map.put("errorMessage", "failed to store");
				return map;
			}
		} catch (IOException e) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to store");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, token);
		
		map.put("imageId", croppedImageId);
		return map;		
	}
	
	public Map<String, String> addWarehousePendingResource(String token, String type, MultipartFile file) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(token);
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==type) || (null==file)) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		if ((0!=type.compareTo("warehouse")) && (0!=type.compareTo("warehouseInside"))) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters - invalid type");
			return map;
		}
		
		// perform resource update
		String imageId;
		try {
			imageId = productDataManager.addWarehousePendingResource(phoneNumber, type, file);
			if (null == imageId) {
				map.put("errorCode", "500");
				map.put("errorMessage", "failed to store");
				return map;
			}
		} catch (IOException e) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to store");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, token);
		
		map.put("imageId", imageId);
		return map;
	}
	
	public Map<String, String> addProductPendingResource(String token, String type, MultipartFile file) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(token);
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==type) || (null==file)) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		if (0 != type.compareTo("product")) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters - invalid type");
			return map;
		}
		
		// perform resource update
		String imageId;
		try {
			imageId = productDataManager.addProductPendingResource(phoneNumber, type, file);
			if (null == imageId) {
				map.put("errorCode", "500");
				map.put("errorMessage", "failed to store");
				return map;
			}
		} catch (IOException e) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to store");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, token);
		
		map.put("imageId", imageId);
		return map;
	}
	
	public void vehicleResource(VehicleResourceRequest req, HttpServletResponse res) throws IOException {
		// validate parameters
		if (null == req.getImageId()) {
			if (logger.isDebugEnabled()) {
				logger.debug("vehicleResource - missing required parameters");
			}
			res.sendError(HttpServletResponse.SC_BAD_REQUEST, "missing parameters");
			return;
		}
				
		// send back resource
		GridFSDBFile file = productDataManager.vehicleResourceById(req.getImageId());
		if (null == file) {
			if (logger.isDebugEnabled()) {
				logger.debug("vehicleResource - image not found, image id " + req.getImageId());
			}
			res.sendError(HttpServletResponse.SC_BAD_REQUEST, "image not found");
			return;
		}
		file.writeTo(res.getOutputStream());
	}
	
	public void warehouseResource(WarehouseResourceRequest req, HttpServletResponse res) throws IOException {
		// validate parameters
		if (null == req.getImageId()) {
			if (logger.isDebugEnabled()) {
				logger.debug("vehicleResource - missing required parameters");
			}
			res.sendError(HttpServletResponse.SC_BAD_REQUEST, "missing parameters");
			return;
		}
		
		// send back resource
		GridFSDBFile file = productDataManager.warehouseResourceById(req.getImageId());
		if (null == file) {
			if (logger.isDebugEnabled()) {
				logger.debug("vehicleResource - image not found, image id " + req.getImageId());
			}
			res.sendError(HttpServletResponse.SC_BAD_REQUEST, "image not found");
			return;
		}
		file.writeTo(res.getOutputStream());
	}
	
	public void productResource(ProductResourceRequest req, HttpServletResponse res) throws IOException {
		// validate parameters
		if (null == req.getImageId()) {
			if (logger.isDebugEnabled()) {
				logger.debug("productResource - missing required parameters");
			}
			res.sendError(HttpServletResponse.SC_BAD_REQUEST, "missing parameters");
			return;
		}
		
		// send back resource
		GridFSDBFile file = productDataManager.productResourceById(req.getImageId());
		if (null == file) {
			if (logger.isDebugEnabled()) {
				logger.debug("productResource - image not found, image id " + req.getImageId());
			}
			res.sendError(HttpServletResponse.SC_BAD_REQUEST, "image not found");
			return;
		}
		file.writeTo(res.getOutputStream());
	}
	
	public Object inReviewPendingList(InReviewVehiclePendingListRequest req) {
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// set up pageable
		int page;
		if (null != req.getPage()) {
			page = (req.getPage().intValue()>=0) ? req.getPage().intValue() : 0;
		} else {
			page = 0;
		}
		int size;
		if (null != req.getSize()) {
			size = (req.getSize().intValue()<100) ? req.getSize().intValue() : 100;
		} else {
			size = 100;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return productDataManager.inReviewPendingList(phoneNumber, new PageRequest(page, size));
	}
	
	public Object inReviewWarehousePendingList(InReviewWarehousePendingListRequest req) {
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// set up pageable
		int page;
		if (null != req.getPage()) {
			page = (req.getPage().intValue()>=0) ? req.getPage().intValue() : 0;
		} else {
			page = 0;
		}
		int size;
		if (null != req.getSize()) {
			size = (req.getSize().intValue()<100) ? req.getSize().intValue() : 100;
		} else {
			size = 100;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return productDataManager.inReviewWarehousePendingList(phoneNumber, new PageRequest(page, size));
	}
	
	public Object inReviewProductPendingList(InReviewProductPendingListRequest req) {
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// set up pageable
		int page;
		if (null != req.getPage()) {
			page = (req.getPage().intValue()>=0) ? req.getPage().intValue() : 0;
		} else {
			page = 0;
		}
		int size;
		if (null != req.getSize()) {
			size = (req.getSize().intValue()<100) ? req.getSize().intValue() : 100;
		} else {
			size = 100;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return productDataManager.inReviewProductPendingList(phoneNumber, new PageRequest(page, size));
	}
	
	public Object approvedVehicleList(ApprovedVehicleListRequest req) {
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// set up pageable
		int page;
		if (null != req.getPage()) {
			page = (req.getPage().intValue()>=0) ? req.getPage().intValue() : 0;
		} else {
			page = 0;
		}
		int size;
		if (null != req.getSize()) {
			size = (req.getSize().intValue()<100) ? req.getSize().intValue() : 100;
		} else {
			size = 100;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return productDataManager.approvedVehicleList(phoneNumber, new PageRequest(page, size));
	}
	
	public Object approvedWarehouseList(ApprovedWarehouseListRequest req) {
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// set up pageable
		int page;
		if (null != req.getPage()) {
			page = (req.getPage().intValue()>=0) ? req.getPage().intValue() : 0;
		} else {
			page = 0;
		}
		int size;
		if (null != req.getSize()) {
			size = (req.getSize().intValue()<100) ? req.getSize().intValue() : 100;
		} else {
			size = 100;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return productDataManager.approvedWarehouseList(phoneNumber, new PageRequest(page, size));
	}
	
	public Object approvedProductList(ApprovedProductListRequest req) {
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// set up pageable
		int page;
		if (null != req.getPage()) {
			page = (req.getPage().intValue()>=0) ? req.getPage().intValue() : 0;
		} else {
			page = 0;
		}
		int size;
		if (null != req.getSize()) {
			size = (req.getSize().intValue()<100) ? req.getSize().intValue() : 100;
		} else {
			size = 100;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return productDataManager.approvedProductList(phoneNumber, new PageRequest(page, size));
	}
	
	public Object rejectedVehicleList(RejectedVehicleListRequest req) {
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// set up pageable
		int page;
		if (null != req.getPage()) {
			page = (req.getPage().intValue()>=0) ? req.getPage().intValue() : 0;
		} else {
			page = 0;
		}
		int size;
		if (null != req.getSize()) {
			size = (req.getSize().intValue()<100) ? req.getSize().intValue() : 100;
		} else {
			size = 100;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());

		return productDataManager.rejectedVehicleList(phoneNumber, new PageRequest(page, size));
	}
	
	public Object rejectedWarehouseList(RejectedWarehouseListRequest req) {
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// set up pageable
		int page;
		if (null != req.getPage()) {
			page = (req.getPage().intValue()>=0) ? req.getPage().intValue() : 0;
		} else {
			page = 0;
		}
		int size;
		if (null != req.getSize()) {
			size = (req.getSize().intValue()<100) ? req.getSize().intValue() : 100;
		} else {
			size = 100;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return productDataManager.rejectedWarehouseList(phoneNumber, new PageRequest(page, size));
	}
	
	public Object rejectedProductList(RejectedProductListRequest req) {
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// set up pageable
		int page;
		if (null != req.getPage()) {
			page = (req.getPage().intValue()>=0) ? req.getPage().intValue() : 0;
		} else {
			page = 0;
		}
		int size;
		if (null != req.getSize()) {
			size = (req.getSize().intValue()<100) ? req.getSize().intValue() : 100;
		} else {
			size = 100;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return productDataManager.rejectedProductList(phoneNumber, new PageRequest(page, size));
	}
	
	public Map<String, String> vehicleCounting(VehicleCountingRequest req) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// compose result
		productDataManager.vehicleCounting(phoneNumber, map);
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> warehouseCounting(WarehouseCountingRequest req) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// compose result
		productDataManager.warehouseCounting(phoneNumber, map);
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> productCounting(ProductCountingRequest req) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// compose result
		productDataManager.productCounting(phoneNumber, map);
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Object vehicleSpecListing(VehicleSpecListingRequest req) {
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// set up pageable
		int page;
		if (null != req.getPage()) {
			page = (req.getPage().intValue()>=0) ? req.getPage().intValue() : 0;
		} else {
			page = 0;
		}
		int size;
		if (null != req.getSize()) {
			size = (req.getSize().intValue()<100) ? req.getSize().intValue() : 100;
		} else {
			size = 100;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());

		return productDataManager.vehicleSpecListing(phoneNumber, new PageRequest(page, size));
	}
	
	public Object warehouseSpecListing(WarehouseSpecListingRequest req) {
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// set up pageable
		int page;
		if (null != req.getPage()) {
			page = (req.getPage().intValue()>=0) ? req.getPage().intValue() : 0;
		} else {
			page = 0;
		}
		int size;
		if (null != req.getSize()) {
			size = (req.getSize().intValue()<100) ? req.getSize().intValue() : 100;
		} else {
			size = 100;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return productDataManager.warehouseSpecListing(phoneNumber, new PageRequest(page, size));
	}
	
	public Object productSpecListing(ProductSpecListingRequest req) {
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// set up pageable
		int page;
		if (null != req.getPage()) {
			page = (req.getPage().intValue()>=0) ? req.getPage().intValue() : 0;
		} else {
			page = 0;
		}
		int size;
		if (null != req.getSize()) {
			size = (req.getSize().intValue()<100) ? req.getSize().intValue() : 100;
		} else {
			size = 100;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return productDataManager.productSpecListing(phoneNumber, new PageRequest(page, size));
	}
	
	public Map<String, String> vehicleSpecStock(VehicleSpecStockRequest req) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if (null == req.getKeySpec()) {
			map.put("errorCode", "401");
			map.put("errorMessage", "invalid parameters");
			return map;
		}
		VehicleSpec spec = productDataManager.findVehicleSpec(phoneNumber, req.getKeySpec());
		if (null == spec) {
			map.put("errorCode", "401");
			map.put("errorMessage", "invalid parameters");
			return map;
		}
		
		// compose response
		map.put("stock", spec.getStock().toString());
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Object vehicleServiceListing(VehicleServiceListingRequest req) {
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// set up pageable
		int page;
		if (null != req.getPage()) {
			page = (req.getPage().intValue()>=0) ? req.getPage().intValue() : 0;
		} else {
			page = 0;
		}
		int size;
		if (null != req.getSize()) {
			size = (req.getSize().intValue()<100) ? req.getSize().intValue() : 100;
		} else {
			size = 100;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return productDataManager.vehicleServiceListing(phoneNumber, new PageRequest(page, size));
	}
	
	public Object warehouseServiceListing(WarehouseServiceListingRequest req) {
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// set up pageable
		int page;
		if (null != req.getPage()) {
			page = (req.getPage().intValue()>=0) ? req.getPage().intValue() : 0;
		} else {
			page = 0;
		}
		int size;
		if (null != req.getSize()) {
			size = (req.getSize().intValue()<100) ? req.getSize().intValue() : 100;
		} else {
			size = 100;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return productDataManager.warehouseServiceListing(phoneNumber, new PageRequest(page, size));
	}
	
	public Object productServiceListing(ProductServiceListingRequest req) {
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// set up pageable
		int page;
		if (null != req.getPage()) {
			page = (req.getPage().intValue()>=0) ? req.getPage().intValue() : 0;
		} else {
			page = 0;
		}
		int size;
		if (null != req.getSize()) {
			size = (req.getSize().intValue()<100) ? req.getSize().intValue() : 100;
		} else {
			size = 100;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return productDataManager.productServiceListing(phoneNumber, new PageRequest(page, size));
	}
	
	public Map<String, String> publishCompleteVehicleService(PublishCompleteVehicleServiceRequest req) {
		Map<String, String> map = new HashMap<String, String>();

		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==req.getKeySpec()) || (null==req.getStartDate()) || (null==req.getUntilDate()) || (null==req.getStock()) || (null==req.getRoutes())) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		if (0 > req.getStock().intValue()) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters - invalid stock");
			return map;
		}
//		DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
//		try {
//			Date availableUntil = formatter.parse(req.getUntilDate());
//			if (availableUntil.before(new Date())) {
//				map.put("errorCode", "400");
//				map.put("errorMessage", "missing parameters - invalid date for available until");
//				return map;
//			}
//		} catch (ParseException e) {
//			map.put("errorCode", "400");
//			map.put("errorMessage", "missing parameters - invalid date for available until");
//			return map;
//		}
		
		// publish service
		if (!productDataManager.publishCompleteVehicleService(phoneNumber, req)) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to publish");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> publishWarehouseService(PublishWarehouseServiceRequest req) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==req.getKeySpec()) || (null==req.getStartDate()) || (null==req.getUntilDate()) || (null==req.getStock()) || (null==req.getPrice())) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		if (0 > req.getStock().intValue()) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters - invalid stock");
			return map;
		}
		DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		try {
			Date availableUntil = formatter.parse(req.getUntilDate());
			if (availableUntil.before(new Date())) {
				map.put("errorCode", "400");
				map.put("errorMessage", "missing parameters - invalid date for available until");
				return map;
			}
		} catch (ParseException e) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters - invalid date for available until");
			return map;
		}
		
		// publish service
		if (!productDataManager.publishWarehouseService(phoneNumber, req)) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to publish");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> publishProductService(PublishProductServiceRequest req) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==req.getKeySpec()) || (null==req.getTitle()) || (null==req.getDescription()) || (null==req.getMinimumVolume()) ||
			(null==req.getPrice()) || (null==req.getStock()) || (null==req.getAvailableStart()) || (null==req.getAvailableUntil())) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		if (0 > req.getStock().intValue()) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters - invalid stock");
			return map;
		}
		DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		try {
			Date availableUntil = formatter.parse(req.getAvailableUntil());
			if (availableUntil.before(new Date())) {
				map.put("errorCode", "400");
				map.put("errorMessage", "missing parameters - invalid date for available until");
				return map;
			}
		} catch (ParseException e) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters - invalid date for available until");
			return map;
		}
		
		// publish service
		if (!productDataManager.publishProductService(phoneNumber, req)) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to publish");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> cancelCompleteVehicleService(CancelCompleteVehicleServiceRequest req) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==req.getKeySpec()) || (null==req.getStartDate()) || (null==req.getUntilDate()) || (null==req.getStock())) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		if (0 > req.getStock().intValue()) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters - invalid stock");
			return map;
		}
		
		// cancel service
		if (!productDataManager.cancelCompleteVehicleService(phoneNumber, req)) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to cancel");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> cancelWarehouseService(CancelWarehouseServiceRequest req) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==req.getKeySpec()) || (null==req.getStartDate()) || (null==req.getUntilDate()) || (null==req.getPrice()) || (null==req.getStock())) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		if (0 > req.getStock().intValue()) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters - invalid stock");
			return map;
		}
		
		// cancel service
		if (!productDataManager.cancelWarehouseService(phoneNumber, req)) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to cancel");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> cancelProductService(CancelProductServiceRequest req) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if (null == req.getKeySpec()) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		
		// cancel service
		if (!productDataManager.cancelProductService(phoneNumber, req)) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to cancel");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> vehicleInfo(VehicleInfoRequest req) {
		Map<String, String> map = new HashMap<String, String>();

		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if (null == req.getVehicleId()) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		
		// retrieve vehicle info
		Map<String, String> result = productDataManager.vehicleInfo(phoneNumber, req.getVehicleId());
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return result;
	}
	
	public Map<String, Object> warehouseInfo(WarehouseInfoRequest req) {
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if (null == req.getWarehouseId()) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		
		// retrieve warehouse info
		Map<String, Object> result = productDataManager.warehouseInfo(phoneNumber, req.getWarehouseId());
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return result;
	}
	
	public Map<String, Object> productInfo(ProductInfoRequest req) {
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if (null == req.getProductId()) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		
		// retrieve product info
		Map<String, Object> result = productDataManager.productInfo(phoneNumber, req.getProductId());
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return result;
	}
	
	public Map<String, String> deleteRejectedVehicle(DeleteRejectedVehicleRequest req) {
		Map<String, String> map = new HashMap<String, String>();

		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if (null == req.getVehicleId()) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		
		// perform deletion
		if (!productDataManager.deleteRejectedVehicle(phoneNumber, req.getVehicleId())) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to delete");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> deleteRejectedWarehouse(DeleteRejectedWarehouseRequest req) {
		Map<String, String> map = new HashMap<String, String>();

		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if (null == req.getWarehouseId()) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		
		// perform deletion
		if (!productDataManager.deleteRejectedWarehouse(phoneNumber, req.getWarehouseId())) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to delete");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> deleteRejectedProduct(DeleteRejectedProductRequest req) {
		Map<String, String> map = new HashMap<String, String>();

		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if (null == req.getProductId()) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		
		// perform deletion
		if (!productDataManager.deleteRejectedProduct(phoneNumber, req.getProductId())) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to delete");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> deleteApprovedVehicle(DeleteApprovedVehicleRequest req) {
		Map<String, String> map = new HashMap<String, String>();

		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if (null == req.getVehicleId()) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		
		// check online presence of the vehicle
		if (productDataManager.checkPresenceOfOnlineVehicle(phoneNumber, req.getVehicleId())) {
			map.put("errorCode", "401");
			map.put("errorMessage", "wrong id or vehicle is online");
			return map;
		}
		
		// perform deletion
		if (!productDataManager.deleteApprovedVehicle(phoneNumber, req.getVehicleId())) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to delete");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> deleteApprovedWarehouse(DeleteApprovedWarehouseRequest req) {
		Map<String, String> map = new HashMap<String, String>();

		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if (null == req.getWarehouseId()) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		
		// check online presence of the warehouse
		if (productDataManager.checkPresenceOfOnlineWarehouse(phoneNumber, req.getWarehouseId())) {
			map.put("errorCode", "401");
			map.put("errorMessage", "wrong id or warehouse is online");
			return map;
		}
		
		// perform deletion
		if (!productDataManager.deleteApprovedWarehouse(phoneNumber, req.getWarehouseId())) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to delete");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> deleteApprovedProduct(DeleteApprovedProductRequest req) {
		Map<String, String> map = new HashMap<String, String>();

		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if (null == req.getProductId()) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		
		// check online presence of the product
		if (productDataManager.checkPresenceOfOnlineProduct(phoneNumber, req.getProductId())) {
			map.put("errorCode", "401");
			map.put("errorMessage", "wrong id or warehouse is online");
			return map;
		}
		
		// perform deletion
		if (!productDataManager.deleteApprovedProduct(phoneNumber, req.getProductId())) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to delete");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> updateVehicleInfo(UpdateVehicleInfoRequest req) {
		Map<String, String> map = new HashMap<String, String>();

		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==req.getVehicleId()) || (null==req.getManInChargeName()) || (null==req.getManInChargePhoneNumber()) || (null==req.getOwner()) || (null==req.getOdometer())) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		
		// perform update
		if (!productDataManager.updateVehicleInfo(phoneNumber, req)) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to update");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> updateWarehouseInfo(UpdateWarehouseInfoRequest req) {
		Map<String, String> map = new HashMap<String, String>();

		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==req.getWarehouseId()) || (null==req.getManInChargeName()) || (null==req.getManInChargePhoneNumber())) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		
		// perform update
		if (!productDataManager.updateWarehouseInfo(phoneNumber, req)) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to update");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> updateProductInfo(UpdateProductInfoRequest req) {
		Map<String, String> map = new HashMap<String, String>();

		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==req.getProductId()) || (null==req.getManInChargeName()) || (null==req.getManInChargePhoneNumber())) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		
		// perform update
		if (!productDataManager.updateProductInfo(phoneNumber, req)) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to update");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> addDriver(AddDriverRequest req) {
		Map<String, String> map = new HashMap<String, String>();

		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==req.getName()) || (null==req.getPhoneNumber()) || (null==req.getGender()) || (null==req.getDrivingAge())) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		
		// add driver
		productDataManager.addDriver(phoneNumber, req);
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> addDriverResource(String token, String type, MultipartFile file) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(token);
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==type) || (null==file)) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		if (0 != type.compareTo("drivingLicense")) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters - invalid type");
			return map;
		}
		
		// perform resource update
		String imageId;
		try {
			imageId = productDataManager.addDriverResource(phoneNumber, type, file);
		} catch (IOException e) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to store");
			return map;
		}
		if (null == imageId) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to store");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, token);
		
		map.put("imageId", imageId);
		return map;
	}
	
	public void driverResource(DriverResourceRequest req, HttpServletResponse res) throws IOException {
		// validate parameters
		if (null == req.getImageId()) {
			if (logger.isDebugEnabled()) {
				logger.debug("driverResource - missing required parameters");
			}
			res.sendError(HttpServletResponse.SC_BAD_REQUEST, "missing parameters");
			return;
		}
		
		// validate token
		String adminPhoneNumber = (String)sessionManager.valueForAdminToken(req.getToken());
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if ((null==phoneNumber) && (null==adminPhoneNumber)) {
			if (logger.isDebugEnabled()) {
				logger.debug("driverResource - token expired");
			}
			res.sendError(HttpServletResponse.SC_BAD_REQUEST, "token expired");
			return;
		}
		
		// send back resource
		GridFSDBFile file = productDataManager.driverResource(req.getImageId());
		if (null == file) {
			if (logger.isDebugEnabled()) {
				logger.debug("driverResource - image not found, image id " + req.getImageId());
			}
			res.sendError(HttpServletResponse.SC_BAD_REQUEST, "image not found");
			return;
		}
		file.writeTo(res.getOutputStream());
		
		// reset token expiration
		if (null != phoneNumber) {
			sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		} else if (null != adminPhoneNumber) {
			sessionManager.resetAdminTokenExpiration(adminPhoneNumber, req.getToken());
		}
	}
	
	public Object driverListing(DriverListingRequest req) {
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// set up pageable
		int page;
		if (null != req.getPage()) {
			page = (req.getPage().intValue()>=0) ? req.getPage().intValue() : 0;
		} else {
			page = 0;
		}
		int size;
		if (null != req.getSize()) {
			size = (req.getSize().intValue()<100) ? req.getSize().intValue() : 100;
		} else {
			size = 100;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());

		return productDataManager.driverListing(phoneNumber, new PageRequest(page, size));
	}
	
	public Map<String, String> updateDriver(UpdateDriverRequest req) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if (null == req.getId()) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		
		// update driver
		if (!productDataManager.updateDriver(phoneNumber, req)) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to update");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> deleteDriver(DeleteDriverRequest req) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if (null == req.getId()) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		
		// delete driver
		if (!productDataManager.deleteDriver(phoneNumber, req.getId())) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to delete");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public List<Map<String, Object>> searchCompleteVehicleService(SearchCompleteVehicleServiceRequest req) {
		// set up pageable
		int page;
		if (null != req.getPage()) {
			page = (req.getPage().intValue()>=0) ? req.getPage().intValue() : 0;
		} else {
			page = 0;
		}
		int size;
		if (null != req.getSize()) {
			size = (req.getSize().intValue()<100) ? req.getSize().intValue() : 100;
		} else {
			size = 100;
		}
		
		return productDataManager.searchCompleteVehicleService(req, new PageRequest(page, size));
	}
	
	public Map<String, String> completeVehicleServiceCounting(CompleteVehicleServiceCountingRequest req) {
		return productDataManager.completeVehicleServiceCounting(req);
	}
	
	public List<Map<String, Object>> searchWarehouseService(SearchWarehouseServiceRequest req) {
		// set up pageable
		int page;
		if (null != req.getPage()) {
			page = (req.getPage().intValue()>=0) ? req.getPage().intValue() : 0;
		} else {
			page = 0;
		}
		int size;
		if (null != req.getSize()) {
			size = (req.getSize().intValue()<100) ? req.getSize().intValue() : 100;
		} else {
			size = 100;
		}
		
		return productDataManager.searchWarehouseService(req, new PageRequest(page, size));
	}
	
	public Map<String, String> warehouseServiceCounting(WarehouseServiceCountingRequest req) {
		return productDataManager.warehouseServiceCounting(req);
	}
	
	public List<Map<String, Object>> searchProductService(SearchProductServiceRequest req) {
		// set up pageable
		int page;
		if (null != req.getPage()) {
			page = (req.getPage().intValue()>=0) ? req.getPage().intValue() : 0;
		} else {
			page = 0;
		}
		int size;
		if (null != req.getSize()) {
			size = (req.getSize().intValue()<100) ? req.getSize().intValue() : 100;
		} else {
			size = 100;
		}
		
		return productDataManager.searchProductService(req, new PageRequest(page, size));
	}
	
	public Map<String, String> productServiceCounting(ProductServiceCountingRequest req) {
		return productDataManager.productServiceCounting(req);
	}
	
	public List<Map<String, Object>> vehiclesForCompleteVehicleService(VehiclesForCompleteVehicleServiceRequest req) {
		if (null == req.getId()) {
			if (logger.isWarnEnabled()) {
				logger.warn("vehiclesForCompleteVehicleService - id is missing");
			}
			return new ArrayList<Map<String, Object>>();
		}
		
		return productDataManager.vehiclesForCompleteVehicleService(req.getId());
	}
	
	public Map<String, Object> warehouseForWarehouseService(WarehouseForWarehouseServiceRequest req) {
		if (null == req.getId()) {
			if (logger.isWarnEnabled()) {
				logger.warn("warehouseForWarehouseService - id is missing");
			}
			return new HashMap<String, Object>();
		}
		
		return productDataManager.warehouseForWarehouseService(req.getId());
	}
	
	public Map<String, Object> productForProductService(ProductForProductServiceRequest req) {
		if (null == req.getId()) {
			if (logger.isWarnEnabled()) {
				logger.warn("warehouseForWarehouseService - id is missing");
			}
			return new HashMap<String, Object>();
		}
		
		return productDataManager.productForProductService(req.getId());
	}
	
	public List<Map<String, String>> transportationTemperatureLevels() {
		List<Map<String, String>> levels = new ArrayList<Map<String, String>>();
		
		List<TransportationTemperature> list = mongoTemplate.findAll(TransportationTemperature.class);
		if (null != list) {
			for (TransportationTemperature temperature : list) {
				Map<String, String> temperatureMap = new HashMap<String, String>();
				temperatureMap.put("identifier", temperature.getIdentifier());
				temperatureMap.put("presentingString", temperature.getPresentingString());
				temperatureMap.put("sorting", temperature.getSorting().toString());
				levels.add(temperatureMap);
			}
		}
		
		return levels;
	}
	
	public List<Map<String, String>> vehicleLengthDef() {
		List<Map<String, String>> def = new ArrayList<Map<String, String>>();
		
		List<VehicleLengthDef> list = mongoTemplate.findAll(VehicleLengthDef.class);
		if (null != list) {
			for(VehicleLengthDef lengthDef : list) {
				Map<String, String> defMap = new HashMap<String, String>();
				defMap.put("identifier", lengthDef.getIdentifier());
				defMap.put("presentingString", lengthDef.getPresentingString());
				defMap.put("sorting", lengthDef.getSorting().toString());
				def.add(defMap);
			}
		}
		
		return def;
	}
	
	public List<Map<String, String>> warehouseTemperatureLevels() {
		List<Map<String, String>> levels = new ArrayList<Map<String, String>>();
		
		List<WarehouseTemperature> list = mongoTemplate.findAll(WarehouseTemperature.class);
		if (null != list) {
			for (WarehouseTemperature temperature : list) {
				Map<String, String> temperatureMap = new HashMap<String, String>();
				temperatureMap.put("identifier", temperature.getIdentifier());
				temperatureMap.put("presentingString", temperature.getPresentingString());
				temperatureMap.put("sorting", temperature.getSorting().toString());
				levels.add(temperatureMap);
			}
		}
		
		return levels;
	}
	
	public List<Map<String, String>> productCategories() {
		List<Map<String, String>> categories = new ArrayList<Map<String, String>>();
		
		List<ProductCategory> list = mongoTemplate.findAll(ProductCategory.class);
		if (null != list) {
			for (ProductCategory category : list) {
				Map<String, String> categoryMap = new HashMap<String, String>();
				categoryMap.put("identifier", category.getIdentifier());
				categoryMap.put("presentingString", category.getPresentingString());
				categoryMap.put("sorting", category.getSorting().toString());
				categories.add(categoryMap);
			}
		}
		
		return categories;
	}
	
	@Autowired
	private SessionManager sessionManager;
	
	@Autowired
	private ProductDataManager productDataManager;
	
	@Autowired
	private IdentityDataManager identityDataManager;
	
	@Autowired
	private MongoTemplate mongoTemplate;
	
	private static final Logger logger = LoggerFactory.getLogger(ProductController.class);
}
